#!/usr/bin/env python3
"""
脚本名称：ch48_exe.py
功能描述： 演示线程的队列,通过生产和消费进行举例
作者：Gavin
创建日期：2025-05-22
版本：1.0
依赖库：无
使用方法： python ch48_exe.py
"""

import threading
import queue
import time

# 创建线程安全队列（最多容纳5个元素）
task_queue = queue.Queue(maxsize=5)


# 生产者线程：生成任务
def producer():
    for i in range(10):
        item = f"任务-{i}"
        task_queue.put(item)  # 若队列满，此处会阻塞
        print(f"[生产者] 添加 {item}，队列大小：{task_queue.qsize()}")
        time.sleep(0.5)
    print("[生产者] 所有任务已提交")


# 消费者线程：处理任务
def consumer():
    while True:
        try:
            # 阻塞获取任务，最多等待2秒
            item = task_queue.get(block=True, timeout=2)
            print(f"[消费者-{threading.current_thread().name}] 处理 {item}")
            time.sleep(1)  # 模拟耗时操作
            task_queue.task_done()  # 必须调用，否则 join() 无法结束
        except queue.Empty:
            print(f"[消费者-{threading.current_thread().name}] 队列已空，退出")
            break


# 启动1个生产者线程和3个消费者线程
producer_thread = threading.Thread(target=producer, name="Producer")
consumer_threads = [
    threading.Thread(target=consumer, name=f"Consumer-{i}")
    for i in range(3)
]

producer_thread.start()
for t in consumer_threads:
    t.start()

# 等待生产者完成
producer_thread.join()

# 等待队列中所有任务被处理
task_queue.join()  # 阻塞直到所有 task_done() 被调用

# 通知消费者线程退出（若未自动退出）
for t in consumer_threads:
    t.join()

print("主线程退出")
